using MediatR;
using ProduceBasicData.Api.Application.Command.ProcessReport;
using ProduceBasicData.Api.DTO;
using ProduceBasicData.Domain.FactoryModeling;
using ProduceBasicData.Domain.ProductionManage;
using ProduceBasicData.ErrorCode;
using ProduceBasicData.Infrastructure.Interface;

namespace ProduceBasicData.Api.Application.Handler.ProcessReport
{
    /// <summary>
    /// 获取工序报工数量处理类
    /// </summary>
    public class GetProcessReportQuantityHandler : IRequestHandler<GetProcessReportQuantityCommand, ApiResult<ProcessReportChartDto>>
    {
        private readonly IBaseRespository<Production_report> _productionReportRepository;
        private readonly IBaseRespository<ProcessModel> _processRepository;

        public GetProcessReportQuantityHandler(
            IBaseRespository<Production_report> productionReportRepository,
            IBaseRespository<ProcessModel> processRepository)
        {
            _productionReportRepository = productionReportRepository;
            _processRepository = processRepository;
        }

        public async Task<ApiResult<ProcessReportChartDto>> Handle(GetProcessReportQuantityCommand request, CancellationToken cancellationToken)
        {
            ApiResult<ProcessReportChartDto> result = new ApiResult<ProcessReportChartDto>();

            try
            {
                var chartData = new ProcessReportChartDto();

                // 获取所有工序
                var allProcesses = _processRepository.GetAll()
                    .Where(x => !x.Isdel)
                    .ToList();

                // 获取生产报工数据
                var productionReports = _productionReportRepository.GetAll()
                    .Where(x => !x.Isdel);

                // 应用日期筛选
                if (request.StartDate.HasValue)
                {
                    productionReports = productionReports.Where(x => x.Production_time >= request.StartDate.Value);
                }

                if (request.EndDate.HasValue)
                {
                    productionReports = productionReports.Where(x => x.Production_time <= request.EndDate.Value);
                }

                // 应用工序筛选
                if (request.ProcessId.HasValue)
                {
                    productionReports = productionReports.Where(x => x.Process_id == request.ProcessId.Value);
                }

                // 应用报工状态筛选
                if (request.ReportStatus.HasValue)
                {
                    productionReports = productionReports.Where(x => x.Report_status == request.ReportStatus.Value);
                }

                // 按工序分组统计数量
                var reportData = productionReports
                    .GroupBy(x => x.Process_id)
                    .Select(g => new ProcessReportQuantityDto
                    {
                        ProcessId = g.Key,
                        Quantity = g.Count()
                    })
                    .ToList();

                // 如果只显示有报工记录的工序
                if (request.OnlyWithReports)
                {
                    // 只处理有报工记录的工序
                    var processIds = reportData.Select(x => x.ProcessId).ToList();
                    var processesWithReports = allProcesses.Where(p => processIds.Contains(p.Id)).ToList();

                    foreach (var report in reportData)
                    {
                        var process = processesWithReports.FirstOrDefault(p => p.Id == report.ProcessId);
                        if (process != null)
                        {
                            report.ProcessName = process.Processname;
                            report.ProcessCode = process.Processcode;
                            report.ProcessDesc = process.Processdesc;
                        }
                    }
                }
                else
                {
                    // 显示所有工序，包括没有报工记录的
                    foreach (var process in allProcesses)
                    {
                        var existingReport = reportData.FirstOrDefault(r => r.ProcessId == process.Id);
                        if (existingReport == null)
                        {
                            reportData.Add(new ProcessReportQuantityDto
                            {
                                ProcessId = process.Id,
                                ProcessName = process.Processname,
                                ProcessCode = process.Processcode,
                                ProcessDesc = process.Processdesc,
                                Quantity = 0
                            });
                        }
                        else
                        {
                            existingReport.ProcessName = process.Processname;
                            existingReport.ProcessCode = process.Processcode;
                            existingReport.ProcessDesc = process.Processdesc;
                        }
                    }
                }

                // 应用排序
                switch (request.SortType)
                {
                    case 1: // 按数量升序
                        reportData = reportData.OrderBy(x => x.Quantity).ToList();
                        break;
                    case 2: // 按数量降序
                        reportData = reportData.OrderByDescending(x => x.Quantity).ToList();
                        break;
                    case 3: // 按工序名称
                        reportData = reportData.OrderBy(x => x.ProcessName).ToList();
                        break;
                    default:
                        reportData = reportData.OrderByDescending(x => x.Quantity).ToList();
                        break;
                }

                // 构建图表数据
                chartData.ProcessNames = reportData.Select(x => x.ProcessName).ToList();
                chartData.Quantities = reportData.Select(x => x.Quantity).ToList();
                chartData.Details = reportData;
                chartData.TotalQuantity = reportData.Sum(x => x.Quantity);
                chartData.ProcessCount = reportData.Count;

                result.Code = ApiEnum.Success;
                result.Msg = "查询成功";
                result.Data = chartData;
            }
            catch (Exception ex)
            {
                result.Code = ApiEnum.Failed;
                result.Msg = $"查询失败：{ex.Message}";
                result.Data = new ProcessReportChartDto();
            }

            return result;
        }
    }
}
